package com.heima.article.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.SelectList;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleConfigMapper;
import com.heima.article.mapper.ApArticleContentMapper;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.ArticleFreemarkerService;
import com.heima.common.contants.RedisConstants;
import com.heima.common.dtos.PageResponseResult;
import com.heima.common.dtos.AppHttpCodeEnum;
import com.heima.common.dtos.PageResponseResult;
import com.heima.common.dtos.ResponseResult;
import com.heima.model.article.dtos.*;
import com.heima.common.exception.LeadNewsException;
import com.heima.model.article.dtos.ApArticleDto;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.dtos.HotArticleVo;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.dtos.WmCommentApplyDto;
import com.heima.model.wemedia.dtos.WmCommentDto;
import com.heima.utils.common.BeanHelper;
import com.heima.utils.common.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {
    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private ApArticleConfigMapper apArticleConfigMapper;
    @Autowired
    private ApArticleContentMapper apArticleContentMapper;
    @Autowired
    private ArticleFreemarkerService articleFreemarkerService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    public ResponseResult<List<ApArticle>> loadArticles(ArticleHomeDto dto, int type) {
        //初始化参数
        if(dto.getMinBehotTime()==null)dto.setMinBehotTime(new Date());
        if(dto.getMaxBehotTime()==null)dto.setMaxBehotTime(new Date());
        if(dto.getSize()==null)dto.setSize(10);

        List<ApArticle> articleList = apArticleMapper.loadArticles(dto,type);

        return ResponseResult.okResult(articleList);
    }

    @Override
    public Long saveOrUpdateApArticle(ArticleDto dto) {

        ApArticle apArticle = BeanHelper.copyProperties(dto,ApArticle.class);

        //判断新增还是修改App文章
        if(dto.getId()==null){
            //新增

            //ap_article表

            save(apArticle);//注意：MyBatis-Plus调用save方法后，apArticle携带了数据库的主键值

            //ap_article_config表
            ApArticleConfig apArticleConfig = new ApArticleConfig();
            apArticleConfig.setArticleId(apArticle.getId());
            apArticleConfig.setIsForward(true);
            apArticleConfig.setIsComment(true);
            apArticleConfig.setIsDown(false);
            apArticleConfig.setIsDelete(false);
            apArticleConfigMapper.insert(apArticleConfig);

            //ap_article_content表
            ApArticleContent apArticleContent = new ApArticleContent();
            apArticleContent.setArticleId(apArticle.getId());
            apArticleContent.setContent(dto.getContent());
            apArticleContentMapper.insert(apArticleContent);

        }else{
            //修改

            //修改ap_article
            updateById(apArticle);

            //修改ap_article_content
            QueryWrapper<ApArticleContent> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("article_id",apArticle.getId());
            ApArticleContent apArticleContent = apArticleContentMapper.selectOne(queryWrapper);
            apArticleContent.setContent(dto.getContent());
            apArticleContentMapper.updateById(apArticleContent);
        }

        //重新文章静态页
        articleFreemarkerService.buildArticleToMinIO(apArticle,dto.getContent());

        //返回文章ID
        return apArticle.getId();
    }

    @Override
    public ResponseResult<List<ApArticle>> loadArticle2(ArticleHomeDto dto, int type) {
        //从redis查询首页文章
        String redisData = redisTemplate.opsForValue().get(RedisConstants.HOT_ARTICLE_FIRST_PAGE + dto.getTag());
        //如果redis有，则返回数据
        if(StringUtils.isNotEmpty(redisData)){
            List<HotArticleVo> hotArticleVos = JsonUtils.toList(redisData, HotArticleVo.class);
            if(CollectionUtils.isNotEmpty(hotArticleVos)) {
                List<ApArticle> articleList = BeanHelper.copyWithCollection(hotArticleVos, ApArticle.class);
                return ResponseResult.okResult(articleList);
            }
        }
        //如果redis没有，则查询数据库
        return loadArticles(dto,type);
    }

    @Override
    public Map<String, Integer> getByUserId(ArticleBehaviorDto articleBehaviorDto) {
        LambdaQueryWrapper<ApArticle> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ApArticle::getAuthorId, articleBehaviorDto.getUserId());
        wrapper.between(ApArticle::getCreatedTime, articleBehaviorDto.getBeginDate(), articleBehaviorDto.getEndDate());
        List<ApArticle> apArticles = apArticleMapper.selectList(wrapper);

        Map<String, Integer> map = new HashMap<>();
        map.put("likesNum", 0);
        map.put("collectNum", 0);
        map.put("publishNum", 0);
        if (CollectionUtils.isEmpty(apArticles)) {
            return map;
        }

        Integer likesNum = 0, collectNum = 0, publishNum = 0;

        for (ApArticle apArticle : apArticles) {
            likesNum += apArticle.getLikes();
            collectNum += apArticle.getCollection();
            if (apArticle.getImages() != null) {
                publishNum += 1;
            }
        }
        map.put("likesNum", likesNum);
        map.put("collectNum", collectNum);
        map.put("publishNum", publishNum);
        return map;
    }

    @Override
    public PageResponseResult findArticleByUserIdAndTime(ArticleBehaviorDto dto) {
        //构建查询条件
        IPage<ApArticle> iPage = new Page<>(dto.getPage(),dto.getSize());
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApArticle::getAuthorId,dto.getUserId());
        queryWrapper.ge(ApArticle::getCreatedTime, dto.getBeginDate());
        queryWrapper.lt(ApArticle::getCreatedTime, dto.getEndDate());

        //执行查询
        iPage = page(iPage,queryWrapper);

        List<ArticleVisitDto> articleVisitStreamMsgs =
                BeanHelper.copyWithCollection(iPage.getRecords(), ArticleVisitDto.class);

        //获取结果进行封装
        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(),dto.getSize(),(int)iPage.getTotal());
        pageResponseResult.setData(articleVisitStreamMsgs);
        pageResponseResult.setErrorMessage("查询成功");

        return pageResponseResult;
    }
    /**
     * 根据用户ID 查询文章
     */
    @Override
    public List<ApArticle> findArticleByUserId(Long uid) {
        if (uid== null){
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }
        LambdaQueryWrapper<ApArticle> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ApArticle::getAuthorId,uid);
        List<ApArticle> apArticleList = apArticleMapper.selectList(wrapper);
        if (!CollectionUtils.isNotEmpty(apArticleList)){
            throw new LeadNewsException(444,"用户还未发表文章");
        }

//        List<Long> longList = apArticleList.stream().map(ApArticle::getId).collect(Collectors.toList());
        return apArticleList;
    }

    /**
     * 根据分页对象 查询文章  已经取消
     * @param dto
     * @return
     */
    @Override
    public PageResponseResult findArticlePage(WmCommentApplyDto dto) {
        //分页对象
        Page<ApArticle> iPage = new Page<>(dto.getPage(),dto.getSize());

        LambdaQueryWrapper<ApArticle> wrapper = new LambdaQueryWrapper<>();
        //文章的作者是本人  dto.getAuthorId已经是Long类型了
        wrapper.eq(ApArticle::getAuthorId,dto.getAuthorId());
        //按照时间范围
        wrapper.between(ApArticle::getPublishTime,dto.getBeginDate(),dto.getEndDate());
        //按照时间逆时针排序
        wrapper.orderByDesc(ApArticle::getPublishTime);
        IPage<ApArticle> apArticleIPage = apArticleMapper.selectPage(iPage, wrapper);


        //获取当前页对象
        List<ApArticle> records = apArticleIPage.getRecords();
        long total = apArticleIPage.getTotal();
        //页面大小
        List<ApArticle> apArticleList = apArticleIPage.getRecords();
        //将ApArticle转换为APArticelDto作为当前页返回
        //
        List<ApArticleDto> articleDtos = BeanHelper.copyWithCollection(apArticleList, ApArticleDto.class);
        for (ApArticleDto articleDto : articleDtos) {
            articleDto.setComments(articleDto.getComment());
        }

        //取出文章id数组  获取文航Config雷彪
        List<Long> collect = apArticleList.stream().map(ApArticle::getId).collect(Collectors.toList());


        List<ApArticleConfig> apArticleConfigs = new ArrayList<>();
        for (Long aLong : collect) {
            LambdaQueryWrapper<ApArticleConfig> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(ApArticleConfig::getArticleId,aLong);
            ApArticleConfig apArticleConfig = apArticleConfigMapper.selectOne(wrapper1);
            if (apArticleConfig!=null){
                apArticleConfigs.add(apArticleConfig);
            }

        }


        //查询是否可以评论
        //遍历集合  将对应的评论添加是否可以评论
        List<ApArticleDto> articleDtoList = new ArrayList<>();
        for (ApArticleDto articleDto : articleDtos) {
            for (ApArticleConfig apArticleConfig : apArticleConfigs) {
                if (articleDto.getId()!=null){
                    if (articleDto.getId().equals(apArticleConfig.getArticleId())){
                        articleDto.setIsComment(apArticleConfig.getIsComment());
                        articleDtoList.add(articleDto);

                    }
                }

            }


//            ApArticleConfig apArticleConfig = apArticleConfigMapper.selectById(articleDto.getId());
//            if (apArticleConfig!=null){
//                articleDto.setIsComment(apArticleConfig.getIsComment());
//            }
        }

        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) apArticleIPage.getTotal());
        pageResponseResult.setData(articleDtos);
        pageResponseResult.setErrorMessage("加载成功");
        return  pageResponseResult;

    }


}
